#!/usr/bin/env python
# Last Change: 2010-03-15 21:09:17

from threading import Lock

def synchronized(lock):
  def wrap(method):
    def newFunction(*args, **kw):
      lock.acquire()
      try:
        return method(*args, **kw)
      finally:
        lock.release()
    return newFunction
  return wrap


def singleton(cls):
  inst = {}
  @synchronized(Lock())
  def getinst():
    if cls not in inst:
      inst[cls] = cls()
    return inst[cls]
  cls.getinst = staticmethod(getinst)
  return cls

def abstract(object):
  t = type(object)
  if t.__name__ == 'classobj' or t.__name__ == 'type':
    cls = object
    method = cls.__init__ if hasattr(cls, '__init__') else None
    def init_method(self, *args, **kw):
      if self.__class__ == cls:
        raise NotImplementedError('abstract method')
      if method:
        method(self, *args, **kw)
    cls.__init__ = init_method
    return cls
  else:
    method = object
    def abstract_method(self, *args, **kw):
      inst_method = getattr(self, method.__name__)
      if hasattr(inst_method, '__is_abstract__'):
        raise NotImplementedError('abstract method')
    abstract_method.__is_abstract__ = True
    return abstract_method

